﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Xsl;
using System.IO;
using System.Configuration;
using System.Reflection;

namespace APH.Parl2.Shared.XML.DocBook
{
    public class XmlRenderer
    {
        public static string Transform(string xmlString)
        {
            // dockbook.xsl has a DTD which is currently parsed
            // however it relies on ..\common\l10n.xml which also has a DTD, and this is not currently parsed

            //string xmlString = "<?xml version='1.0' encoding='utf-8'?><article xmlns='http://docbook.org/ns/docbook' version='5.0' xml:lang='en'><title>Sample article</title><para>This is a very short article.</para></article>";
            //string htmlFile = @"C:\xml\myarticle.html";

            //string xsltPath = @"C:\Users\Slava.Barouline\Documents\Visual Studio 2010\Projects\parl2\XmlRenderer\html\docbook.xsl";
            string xsltPath = @"DocBook\docbook-xsl\html\docbook.xsl";

            var renderer = new XmlRenderer();

            string output = renderer.TransformXmlStringToString(xsltPath, xmlString);

            return output;
        }

        public void TransformXmlStringToFile(string xsltPath, string xmlString, string htmlFile)
        {
            // Create a stream from the input xml string
            XmlReader inputXml = ConvertXmlStringToStream(xmlString);

            // Set up a stream for the output html
            XmlWriter outputHtml = SetUpHtmlOutputFileStream(htmlFile);

            XslCompiledTransform xslt = new XslCompiledTransform();

            // Load the style sheet.
            XmlReader reader = SetupReaderForStylesheet(xsltPath);
            XsltSettings xsltSettings = SetTransformationProperties();
            XmlUrlResolver resolver = CreateDefaultResolver();

            xslt.Load(reader, xsltSettings, resolver);

            // Perform the transformation
            xslt.Transform(inputXml, outputHtml);
        }


        public string TransformXmlStringToString(string xsltPath, string xmlString)
        {
            // Create a stream from the input xml string
            XmlReader inputXml = ConvertXmlStringToStream(xmlString);

            // Set up a stream for the output html
            StringBuilder output = new StringBuilder();
            XmlWriter outputHtml = SetUpHtmlOutputStringStream(output);

            XslCompiledTransform xslt = new XslCompiledTransform();

            // Load the style sheet.
            XmlReader reader = SetupReaderForStylesheet(xsltPath);
            XsltSettings xsltSettings = SetTransformationProperties();
            XmlUrlResolver resolver = CreateDefaultResolver();

            xslt.Load(reader, xsltSettings, resolver);

            // Perform the transformation
            xslt.Transform(inputXml, outputHtml);

            return output.ToString();
        }
        private static XsltSettings SetTransformationProperties()
        {
            XsltSettings xsltSettings = new XsltSettings();
            xsltSettings.EnableDocumentFunction = true;
            xsltSettings.EnableScript = false;
            return xsltSettings;
        }

        private static XmlReader SetupReaderForStylesheet(string xsltPath)
        {
            XmlReaderSettings readerSettings = new XmlReaderSettings();
            readerSettings.DtdProcessing = DtdProcessing.Parse;

            var uri = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase), xsltPath);
            XmlReader reader = XmlTextReader.Create(uri, readerSettings);
            return reader;
        }

        private XmlWriter SetUpHtmlOutputFileStream(string htmlFile)
        {
            XmlWriterSettings writerSettings = new XmlWriterSettings();
            writerSettings.Indent = true;
            writerSettings.IndentChars = "\t";
            writerSettings.ConformanceLevel = ConformanceLevel.Auto;
            XmlWriter outputHtml = XmlWriter.Create(htmlFile, writerSettings);
            return outputHtml;

        }

        private static XmlWriter SetUpHtmlOutputStringStream(StringBuilder output)
        {
            XmlWriterSettings writerSettings = new XmlWriterSettings();
            writerSettings.Indent = true;
            writerSettings.IndentChars = "\t";
            writerSettings.ConformanceLevel = ConformanceLevel.Auto;
            XmlWriter outputHtml = XmlWriter.Create(output, writerSettings);
            return outputHtml;
        }

        private static XmlReader ConvertXmlStringToStream(string xmlString)
        {
            StringReader strReader = new StringReader(xmlString);
            XmlReader inputXml = XmlTextReader.Create(strReader);
            return inputXml;
        }

        private static XmlUrlResolver CreateDefaultResolver()
        {
            XmlUrlResolver resolver = new XmlUrlResolver();
            resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;
            return resolver;
        }
    }
    
    

}
